package com.genwangsun.nettydemo.websocket;

import cn.hutool.json.JSONUtil;
import com.genwangsun.nettydemo.bo.WebsocketMessage;
import com.genwangsun.nettydemo.entity.User;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author GenWangSun
 * websocket的业务功能逻辑处理
 *
 */
@Component
@ChannelHandler.Sharable
@Slf4j
public class WebSocketServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    public static final ChannelGroup CHANNEL_GROUP = new DefaultChannelGroup("ChannelGroups", GlobalEventExecutor.INSTANCE);

    public static ConcurrentHashMap<Channel, WebsocketMessage> channelMap = new ConcurrentHashMap<>();

    @Autowired
    private RedissonClient redisClient;

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) {
        String text = textWebSocketFrame.text();
        log.info("webSocket消息接收成功, 消息体:{}", text);
        User message = JSONUtil.toBean(textWebSocketFrame.text(), User.class);
        log.info("format , 消息体:{}", message);
        for (Channel channel : CHANNEL_GROUP) {
            RTopic topic = redisClient.getTopic("myTopic");
            long clientsReceivedMessage = topic.publish(message);
            channel.writeAndFlush(clientsReceivedMessage);
        }

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("channelActive...");
        InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();

        String clientIp = ipSocket.getAddress().getHostAddress();
        log.info("收到客户端[ip:" + ipSocket + "]连接");
        CHANNEL_GROUP.add(ctx.channel());
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.info("channelInactive...");
        CHANNEL_GROUP.remove(ctx.channel());
    }
}
